import ReactDOM from 'react-dom';
import React, { useEffect, useState } from 'react';
import {
  HashRouter ,
  Route,
  Routes,
  Link,
  useParams,
} from 'react-router-dom';
import { createHashHistory } from 'history';
import { Loading, Shell, Search, Nav } from '@alifd/next';
import { buildComponents, assetBundle, AssetLevel, AssetLoader } from '@alilc/lowcode-utils';
import ReactRenderer from '@alilc/lowcode-react-renderer';
import { injectComponents } from '@alilc/lowcode-plugin-inject';
import appHelper from './appHelper';
import { getProjectSchemaFromLocalStorage, getPackagesFromLocalStorage, getPreviewLocale, setPreviewLocale, getResourceListFromLocalStorage } from './services/mockService';
import { isDef } from './shared/functions';

const getScenarioName = function () {
  if (location.search) {
    return new URLSearchParams(location.search.slice(1)).get('scenarioName') || 'general';
  }
  return 'general';
}

const basePath = `/preview.html`;

const history = createHashHistory();

const SamplePreview = () => {
  const params = useParams();

  const { path } = params;

  const [resource, setResource] = useState({});

  const [isRender, setIsRender] = useState(false);

  const scenarioName = getScenarioName();

  const currentLocale = getPreviewLocale(getScenarioName());

  useEffect(() => {
    getResource();
    if (!isDef(appHelper.utils.customHistory)) {
      appHelper.utils.customHistory = history;
    }
    if (!isDef((window as any).setPreviewLocale)) {
      (window as any).setPreviewLocale = (locale:string) => setPreviewLocale(getScenarioName(), locale);
    }
  }, [path])

  async function getResource() {
    setIsRender(false);
    const resourceList = await getResourceListFromLocalStorage(scenarioName);
    const curResource = resourceList.find((r) => r.path === path) || resourceList[0];
    if (!isDef(curResource)) return;
    const id = curResource.id || resourceList?.[0].id;
    const packages = getPackagesFromLocalStorage(scenarioName, id);
    const projectSchema = getProjectSchemaFromLocalStorage(scenarioName, id);
    const {
      componentsMap: componentsMapArray,
      componentsTree,
      i18n,
    } = projectSchema;
    const componentsMap: any = {};
    componentsMapArray.forEach((component: any) => {
      componentsMap[component.componentName] = component;
    });
    const pageSchema = componentsTree[0];

    const libraryMap = {};
    const libraryAsset = [];
    packages.forEach(({ package: _package, library, urls, renderUrls }) => {
      libraryMap[_package] = library;
      if (renderUrls) {
        libraryAsset.push(renderUrls);
      } else if (urls) {
        libraryAsset.push(urls);
      }
    });

    const vendors = [assetBundle(libraryAsset, AssetLevel.Library)];

    // TODO asset may cause pollution
    const assetLoader = new AssetLoader();
    await assetLoader.load(libraryAsset);
    const components = await injectComponents(buildComponents(libraryMap, componentsMap));
    // console.log(projectSchema, pageSchema, libraryAsset, components)

    setResource({
      id,
      schema: {
        ...pageSchema,
      },
      components,
      i18n,
      resourceList,
    });
    setIsRender(true);
  }

  const { id, schema, components, i18n = {}, resourceList = [] } = resource as any;

  if (!schema || !components) {
    return <Loading fullScreen />;
  }

  return (
    <div className="lowcode-plugin-sample-preview">
      <Shell
        className={"iframe-hack"}
        device="desktop"
        style={{ border: "1px solid #eee" }}
      >
        <Shell.Branding>
          <div className="rectangular"></div>
          <span style={{ marginLeft: 10 }}>App Name</span>
        </Shell.Branding>
        <Shell.Navigation direction="hoz">
          <Search
            key="2"
            shape="simple"
            type="dark"
            palceholder="Search"
            style={{ width: "200px" }}
          />
        </Shell.Navigation>

        <Shell.Navigation>
          <Nav
            embeddable
            aria-label="global navigation"
            selectedKeys={[id || resourceList[0].id || '']}
          >
            {
              resourceList.map((d) => (
                <Nav.Item
                  key={d.id}
                  icon="account"
                ><Link to={`/${d.path || ''}`} >{d.title} </Link></Nav.Item>
              ))
            }
          </Nav>
        </Shell.Navigation>

        <Shell.Content>
          <div style={{ minHeight: 1200, background: "#fff" }}>
            {
              isRender && <ReactRenderer
                className="lowcode-plugin-sample-preview-content"
                schema={schema}
                components={components}
                locale={currentLocale}
                messages={i18n}
                appHelper={appHelper}
              />
            }
          </div>
        </Shell.Content>
      </Shell>
    </div>
  );
};

ReactDOM.render(<HashRouter >
  <Routes>
    <Route path={`/`} element={<SamplePreview />} />
    <Route path={`/:path`} element={<SamplePreview />} />
  </Routes>
</HashRouter>, document.getElementById('ice-container'));
